package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.lang.UUID;
import com.alibaba.nacos.common.utils.StringUtils;
import com.atguigu.tingshu.album.service.TestService;
import com.atguigu.tingshu.model.album.AlbumInfo;
import io.swagger.v3.oas.annotations.security.OAuthFlow;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ReactiveRedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author Wu Xingbin
 * @date 2023/11/27/16:57
 */
@Service
public class TestServiceImpl implements TestService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


//    @Override
//    public void testLock() {
//        try {
//            //1.从Redis缓存中获取key="num"的值  保证redis中存在"num"(手动提前在redis中创建key)
//            String s = stringRedisTemplate.opsForValue().get("num");
//            if (StringUtils.isBlank(s)) {
//                return;
//            }
//            //2.对获取到值进行+1操作
//            int number = Integer.parseInt(s);
//            stringRedisTemplate.opsForValue().set("number", String.valueOf(++number));
//        } catch (NumberFormatException e) {
//            e.printStackTrace();
//        }
//    }

    /* @Override
     public void testLock() {

         //申明一个uuid
         String uuid = UUID.randomUUID().toString();
         //0.先尝试获取锁 setnx key val
         Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent("lock", uuid, 3, TimeUnit.SECONDS);
         if (aBoolean) {
             try {
                 //获取锁成功，执行业务代码
                 //1.先从redis中通过key num获取值  key提前手动设置 num 初始值：0
                 String s = stringRedisTemplate.opsForValue().get("num");
                 if (StringUtils.isBlank(s)) {
                     return;
                 }
                 //2.如果值为空则非法直接返回即可
                 //3.对num值进行自增加一
                 int num = Integer.parseInt(s);
                 stringRedisTemplate.opsForValue().set("num", String.valueOf(++num));
                 //判断是否是一样的uuid
                 if (uuid.equals(stringRedisTemplate.opsForValue().get("lock"))) {
                     //4.将锁释放
                     stringRedisTemplate.delete("lock");
                 }
             } catch (NumberFormatException e) {
                 e.printStackTrace();
             }
         } else {
             try {
                 Thread.sleep(25);
                 this.testLock();
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }*/
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void testLock() {
        try {
            //先尝试获取分布式锁 1.创建锁对象  2.调用获取锁方法
            RLock lock = redissonClient.getLock("lock");

            //获取锁成功后，才执行业务
            lock.lock();  //阻塞到获取锁成功为止
            //lock.tryLock(5, TimeUnit.SECONDS);  //参数1：等待锁获取最大时间  参数2：时间单位  获取锁失败返回false
            //lock.tryLock(3, 5, TimeUnit.SECONDS);//参数1：等待锁获取最大时间  参数2：锁过期时间，参数3：时间单位  获取锁失败返回false

            try {
                //1.从Redis缓存中获取key="num"的值  保证redis中存在"num"(手动提前在redis中创建key)
                String value = (String) redisTemplate.opsForValue().get("num");
                if (StringUtils.isBlank(value)) {
                    return;
                }
                //2.对获取到值进行+1操作
                int num = Integer.parseInt(value);
                redisTemplate.opsForValue().set("num", String.valueOf(++num));
            } finally {
                //业务执行完毕释放锁
                lock.unlock();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
